package c.c.d.s.s.o.c.as.configuration.csrf;

import c.c.d.s.s.o.c.as.configuration.csrf.strategy.AbstractCsrfStrategy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Description: CSRF 策略标准
 *
 * @author LiKe
 * @version 1.0.0
 * @date 2020-08-12 13:09
 */
public abstract class AbstractCsrfStrategyAspect {

    /**
     * Description: 选举合适的策略
     *
     * @param parameters 用于策略选举的参数
     * @return {@link AbstractCsrfStrategy} 的实现类
     * @author LiKe
     * @date 2020-08-11 19:00:26
     */
    protected AbstractCsrfStrategy decide(Map<String, ?> parameters, List<? extends AbstractCsrfStrategy> delegates) {
        // ~ 选举出匹配的策略
        final List<? extends AbstractCsrfStrategy> candidates = delegates.stream().filter(delegate -> delegate.supports(parameters)).collect(Collectors.toList());
        final int eligibleStrategyNum = candidates.size();

        if (eligibleStrategyNum == 0) {
            return null;
        } else if (eligibleStrategyNum > 1) {
            // ~ 有匹配的多个策略
            throw new AmbiguousCsrfStrategyException(eligibleStrategyNum);
        } else {
            // ~ 返回合适的策略
            return candidates.get(0);
        }
    }

    protected Map<String, ?> extractParameters(ProceedingJoinPoint proceedingJoinPoint) {
        return JSON.parseObject(JSON.toJSONString(proceedingJoinPoint.getArgs()[1]), new TypeReference<Map<String, ?>>() {
        });
    }
}
